using B.S.NewMedical.Api.Write.Application.Command.Doctor;
using B.S.NewMedical.Domain.Doctor;
using B.S.NewMedical.ErrorCode;
using B.S.NewMedical.Infrastructure;
using B.S.NewMedical.Infrastructure.Interface;
using MediatR;

namespace B.S.NewMedical.Api.Write.Application.Handler.Doctor
{
    /// <summary>
    /// 创建开单申请处理器
    /// </summary>
    public class CreatePrescriptionHandler : IRequestHandler<CreatePrescriptionCommand, ApiResult<int>>
    {
        private readonly IBaseRepository<PrescriptionApplicationModel> _prescriptionRepository;
        private readonly IBaseRepository<PrescriptionDetailModel> _detailRepository;
        private readonly MyDbcontext _dbContext;
        private readonly ILogger<CreatePrescriptionHandler> _logger;

        public CreatePrescriptionHandler(
            IBaseRepository<PrescriptionApplicationModel> prescriptionRepository,
            IBaseRepository<PrescriptionDetailModel> detailRepository,
            MyDbcontext dbContext,
            ILogger<CreatePrescriptionHandler> logger)
        {
            _prescriptionRepository = prescriptionRepository;
            _detailRepository = detailRepository;
            _dbContext = dbContext;
            _logger = logger;
        }

        public async Task<ApiResult<int>> Handle(CreatePrescriptionCommand request, CancellationToken cancellationToken)
        {
            // 参数验证
            if (request.HospitalId <= 0)
                return new ApiResult<int> { Code = ApiEnum.Fail, Msg = "医院ID不能为空" };

            if (request.UserId <= 0)
                return new ApiResult<int> { Code = ApiEnum.Fail, Msg = "用户ID不能为空" };

            if (string.IsNullOrWhiteSpace(request.ApplyReason))
                return new ApiResult<int> { Code = ApiEnum.Fail, Msg = "申请原因不能为空" };

            if (request.Details == null || !request.Details.Any())
                return new ApiResult<int> { Code = ApiEnum.Fail, Msg = "开单明细不能为空" };

            // 验证总金额
            decimal calculatedTotal = request.Details.Sum(d => d.Amount);
            if (Math.Abs(calculatedTotal - request.TotalAmount) > 0.01m)
                return new ApiResult<int> { Code = ApiEnum.Fail, Msg = "总金额与明细金额不匹配" };

            try
            {
                // 开启事务
                using (var transaction = await _dbContext.Database.BeginTransactionAsync(cancellationToken))
                {
                    try
                    {
                        // 创建开单申请
                        var prescription = new PrescriptionApplicationModel
                        {
                            HospitalId = request.HospitalId,
                            UserId = request.UserId,
                            ApplicationTime = DateTime.Now,
                            Status = 0, // 待审核
                            TotalAmount = request.TotalAmount,
                            ApplyReason = request.ApplyReason,
                            CreateTime = DateTime.Now,
                            AuditorId=request.AuditorId,
                            IsDeleted = false
                        };

                        // 保存开单申请
                        await _prescriptionRepository.CreateAsync(prescription);

                        // 创建开单明细
                        var details = new List<PrescriptionDetailModel>();
                        foreach (var item in request.Details)
                        {
                            var detail = new PrescriptionDetailModel
                            {
                                ApplicationId = prescription.Id,
                                ItemType = item.ItemType,
                                ItemId = item.ItemId,
                                Quantity = item.Quantity,
                                UnitPrice = item.UnitPrice,
                                Amount = item.Amount,
                                CreateTime = DateTime.Now,
                                IsDeleted = false
                            };
                            details.Add(detail);
                        }

                        // 批量保存明细
                        foreach (var detail in details)
                        {
                            await _detailRepository.CreateAsync(detail);
                        }

                        // 提交事务
                        await transaction.CommitAsync(cancellationToken);

                        _logger.LogInformation("成功创建开单申请，ID：{PrescriptionId}", prescription.Id);

                        return new ApiResult<int>
                        {
                            Code = ApiEnum.Success,
                            Msg = "创建开单申请成功",
                            Data = prescription.Id
                        };
                    }
                    catch (Exception ex)
                    {
                        // 回滚事务
                        await transaction.RollbackAsync(cancellationToken);
                        _logger.LogError(ex, "创建开单申请失败");
                        throw;
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建开单申请时发生异常");
                return new ApiResult<int>
                {
                    Code = ApiEnum.Error,
                    Msg = "创建开单申请失败：" + ex.Message
                };
            }
        }
    }
} 